package com.mach.platform.service;

import com.mach.platform.domain.base.Role;
import com.mach.platform.repository.RoleRepo;
import com.mach.platform.utils.DateUtil;
import com.mach.platform.utils.PinYinUtil;
import com.mach.platform.utils.security.SecurityUtils;
import com.mach.platform.utils.springdata.DynamicSpecifications;
import com.mach.platform.utils.springdata.SearchFilter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.transaction.Transactional;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author Anonymous
 * @Description: 角色实现类
 * @Package: com.mach.platform.com.mach.platform.service
 * @time 2018/04/12 17:46
 */
@Service
public class RoleServiceImpl implements RoleService {

	@Autowired
	private RoleRepo roleRepo;

	@PersistenceContext
	private EntityManager em;

	/**
	 * 保存
	 *
	 * @param role 保存的实体
	 * @return
	 */
	@Transactional(rollbackOn = Exception.class)
	@Override
	public Role save (Role role) {
		role.setCreationBy(SecurityUtils.getCurrentUserName());
		role.setCreationTime(DateUtil.getYMDHMS());

		if (role.getContent() == null) {
			role.setContent("ROLE_" + PinYinUtil.getPingYin(role.getName()).toUpperCase());
		}

		Role dbResult = roleRepo.saveAndFlush(role);

		String sql = "insert into role_menu (role_id, menu_id) values (" +dbResult.getId()+ ", 1), ("+ dbResult.getId()+", 2)";
		em.createNativeQuery(sql).executeUpdate();

		return dbResult;
	}

	/**
	 * 插入，批量保存
	 *
	 * @param list
	 * @return
	 */
	@Override
	public List<Role> insertObjInBatch (List<Role> list) {
		return null;
	}

	/**
	 * 更新
	 *
	 * @param role 跟新的实体
	 * @return
	 */
	@Transactional(rollbackOn = Exception.class)
	@Override
	public Role update (Role role) {

		role.setUpdateBy(SecurityUtils.getCurrentUserName());
		role.setUpdateTime(DateUtil.getYMDHMS());
		Role dbResult = roleRepo.saveAndFlush(role);

		return dbResult;
	}

	/**
	 * 删除--批量删除
	 *
	 * @param ids 批量删除id
	 * @return
	 */
	@Transactional(rollbackOn = Exception.class)
	@Override
	public int delete (Long[] ids) {

		Integer effectedNums = roleRepo.deleteByIdIn(ids);
		Arrays.stream(ids).forEach(id -> {
			// 删除菜单关系
			roleRepo.delMenuRelationByRoleIdAll(id);
			// 删除 用户关系
			roleRepo.delUserRelationByRoleId(id);
		});

		return effectedNums;
	}

	/**
	 * 获取列表数据
	 *
	 * @param pageable
	 * @param params
	 * @return
	 */
	@Override
	public Page<Role> list (Pageable pageable, Map params) {

		Specification conditions = DynamicSpecifications
				                           .bySearchFilter(SearchFilter.parse(params).values(), Role.class);

		Page<Role> dbResult = roleRepo.findAll(conditions, pageable);

		return dbResult;
	}

	/**
	 * 获取单体 数据
	 *
	 * @param id 获取详情的id
	 * @return
	 */
	@Override
	public Role info (Long id) {
		return null;
	}

	@Transactional(rollbackOn = Exception.class)
	@Override
	public int insertUserRealtion (Long roleId, List<Long> userId) {

		//保护 超级管理员角色以及去重
		List<Long> uniqList = userId.stream().distinct().filter(id -> !id.equals(1L)).collect(Collectors.toList());

		int resultEffections = 0;
		roleRepo.delUserRelationByRoleId(roleId);
		if (userId.size()>0) {
			StringBuilder sb = new StringBuilder();
			sb.append("insert into role_account (role_id, account_id) values ");
			for (int i = 0; i < uniqList.size(); i++) {
				if (i > 0) {
					sb.append(",");
				}
				sb.append("(" + roleId + "," + uniqList.get(i) + ")");
			}
			System.out.println(sb.toString());
			resultEffections = em.createNativeQuery(sb.toString()).executeUpdate();
		}

		return resultEffections;
	}

    @Transactional(rollbackOn = Exception.class)
    @Override
    public int insertMenuRealtion(Long roleId, List<Long> menuIds) {

        int resultEffections = 0;
        roleRepo.delMenuRelationByRoleId(roleId);
        if (menuIds.size()>0) {
            StringBuilder sb = new StringBuilder();
            sb.append("insert into role_menu (role_id, menu_id) values ");
            for (int i = 0; i < menuIds.size(); i++) {
                if (i > 0) {
                    sb.append(",");
                }
                sb.append("(" + roleId + "," + menuIds.get(i) + ")");
            }
            resultEffections = em.createNativeQuery(sb.toString()).executeUpdate();
        }
        return resultEffections;
    }
}
